import axios from 'axios'
import store from '/@/store/Index'
import router from '/@/router/Index'
import { ElMessage } from 'element-plus'
import qs from 'qs'

function redirectLogin() {
  router.push({
    name: 'login',
    query: {
      redirect: router.currentRoute.fullPath
    }
  })
}

function refreshToken() {
  return axios.create()({
    method: 'POST',
    url: '/front/user/refresh_token',
    data: qs.stringify({
      // refresh_token 只能使用1次
      refreshtoken: store.state.user.refresh_token
    })
  })
}

const request = axios.create({
  // 配置选项
  // baseURL,
  // timeout
})

// 请求拦截器
request.interceptors.request.use(
  function (config) {
    const { user } = store.state
    if (user && user.access_token) {
      config.headers.Authorization = user.access_token
    }
    return config
  },
  function (error) {
    return Promise.reject(error)
  }
)

// 响应拦截器
let isRefreshing = false // 控制刷新token的状态
let requests: any[] = [] // 存储刷新token期间过来的401请求
request.interceptors.response.use(
  function (response) {
    return response
  },
  async function (error) {
    if (error.response) {
      const { status } = error.response
      if (status === 400) {
        ElMessage.error('请求参数错误')
      } else if (status === 401) {
        // token无效
        if (!store.state.user) {
          redirectLogin()
          return Promise.reject(error)
        }

        // 判断刷新状态
        if (!isRefreshing) {
          isRefreshing = true // 开启刷新状态
          // 尝试刷新获取新的token
          return refreshToken()
            .then((res) => {
              if (!res.data.success) {
                throw new Error('刷新token失败')
              } else {
                // 刷新token成功
                store.commit('setUser', res.data.content)
                // 把request队列中的请求重新发出
                requests.forEach((cb) => cb())
                requests = []
                return request(error.config)
              }
            })
            .catch((error) => {
              store.commit('setUser', null)
              redirectLogin()
              return Promise.reject(error)
            })
            .finally(() => {
              isRefreshing = false // 重置刷新状态
            })
        }
        // 刷新状态下，把请求挂起
        return new Promise((resolve) => {
          requests.push(() => {
            resolve(request(error.config))
          })
        })
      } else if (status === 403) {
        ElMessage.error('没有权限，请联系管理员')
      } else if (status === 404) {
        ElMessage.error('请求资源不存在')
      } else if (status >= 500) {
        ElMessage.error('服务端错误，请联系管理员')
      }
    } else if (error.request) {
      // 超时
      ElMessage.error('请求超时, 请刷新重试')
    } else {
      ElMessage.error(`请求失败: ${error.message}`)
    }
    return Promise.reject(error)
  }
)

export default request
